﻿/*----------------------------------------------------------------
//  <copyright file="UserBase.cs" company="MicroCloud@151504200868">
//      Copyright © 2020-2024 MicroCloud Corporation, All rights reserved.
//  </copyright>
//  <site>https://gitee.com/chenmm123/microclouds</site>
//  <last-editor>cmm</last-editor>
//  <last-date>2023-12-06 18:34</last-date>
//----------------------------------------------------------------*/

using EmailAddressAttribute = MicroCloud.Utils.EmailAddressAttribute;

namespace MicroCloud.Identity.Entities
{
    #region "用户信息基类"
    /// <summary>
    /// 用户信息基类
    /// </summary>
    /// <typeparam name="TKey">用户编号类型</typeparam>
    public abstract class UserBase<TKey> : EntityBase<TKey>, ILockable, ICreatedTime, ISoftDeletable
        where TKey : struct, IEquatable<TKey>
    {
        #region "属性"
        #region "获取或设置 用户名"
        private string _UserName = "";
        /// <summary>
        /// 获取或设置 用户名
        /// </summary>
        [Column("UserName")]
        [Required, DefaultValue("")]
        [StringSize(StringSizeType.Name)]
        [DisplayName("用户名")]
        public string UserName { get { return _UserName; } set { _UserName = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 标准化用户名"
        private string _NormalizedUserName = "";
        /// <summary>
        /// 获取或设置 标准化用户名
        /// </summary>
        [Column("NormalizedUserName")]
        [Required, DefaultValue("")]
        [StringSize(StringSizeType.Name)]
        [DisplayName("标准化用户名"), AuditIgnore]
        public string NormalizedUserName { get { return _NormalizedUserName; } set { _NormalizedUserName = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 用户昵称"
        private string _NickName = "";
        /// <summary>
        /// 获取或设置 用户昵称
        /// </summary>
        [Column("NickName")]
        [Required, DefaultValue("")]
        [StringSize(StringSizeType.Name)]
        [DisplayName("用户昵称")]
        public string NickName { get { return _NickName; } set { _NickName = value.ReplaceNull(); } }
        #endregion

        #region "获取或设置 电子邮箱"
        private string _Email = "";
        /// <summary>
        /// 获取或设置 电子邮箱
        /// </summary>
        [Column("Email")]
        [EmailAddress]
        [StringSize(StringSizeType.Code)]
        [DisplayName("电子邮箱")]
        public string Email { get { return _Email; } set { _Email = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 标准化电子邮箱"
        private string _NormalizeEmail = "";
        /// <summary>
        /// 获取或设置 标准化电子邮箱
        /// </summary>
        [Column("NormalizeEmail")]
        [AuditIgnore]
        [EmailAddress]
        [StringSize(StringSizeType.Code)]
        [DisplayName("标准化电子邮箱")]
        public string NormalizeEmail { get { return _NormalizeEmail; } set { _NormalizeEmail = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 邮箱是否已确认"
        /// <summary>
        /// 获取或设置 邮箱是否已确认
        /// </summary>
        [Column("EmailConfirmed")]
        [DisplayName("邮箱确认")]
        public bool EmailConfirmed { get; set; }
        #endregion

        #region "获取或设置 手机号码"
        private string _PhoneNumber = "";
        /// <summary>
        /// 获取或设置 手机号码
        /// </summary>
        [Column("PhoneNumber")]
        [MobileNumber]
        [StringSize(StringSizeType.Key)]
        [DisplayName("手机号码")]
        public string PhoneNumber { get { return _PhoneNumber; } set { _PhoneNumber = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 手机是否已确认"
        /// <summary>
        /// 获取或设置 手机是否已确认
        /// </summary>
        [Column("PhoneConfirmed")]
        [DisplayName("手机确认")]
        public bool PhoneConfirmed { get; set; }
        #endregion

        #region "获取或设置 密码哈希值"
        private string _PasswordHash = "";
        /// <summary>
        /// 获取或设置 密码哈希值
        /// </summary>
        [Column("PasswordHash")]
        [StringMax]
        [DisplayName("密码哈希值"), AuditIgnore]
        public string PasswordHash { get { return _PasswordHash; } set { _PasswordHash = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 一个标志，指示是否为该用户启用了双因子身份验证。"
        /// <summary>
        /// 获取或设置 一个标志，指示是否为该用户启用了双因子身份验证。
        /// </summary>
        [Column("TwoFactorEnabled")]
        [DisplayName("双因子身份验证")]
        public bool TwoFactorEnabled { get; set; }
        #endregion
        #region "获取或设置 当任何用户锁定结束时，UTC的日期和时间。"
        /// <summary>
        /// 获取或设置 当任何用户锁定结束时，UTC的日期和时间。
        /// </summary>
        [Column("LockoutEnd")]
        [DisplayName("锁定时间")]
        public DateTimeOffset? LockoutEnd { get; set; }
        #endregion
        #region "获取或设置 指示用户是否可以被锁定的标志"
        /// <summary>
        /// 获取或设置 指示用户是否可以被锁定的标志
        /// </summary>
        [Column("LockoutEnabled")]
        [DisplayName("是否登录锁")]
        public bool LockoutEnabled { get; set; }
        #endregion
        #region "获取或设置 当前用户失败的登录尝试次数"
        /// <summary>
        /// 获取或设置 当前用户失败的登录尝试次数
        /// </summary>
        [Column("AccessFailedCount")]
        [DisplayName("登录失败次数")]
        public int AccessFailedCount { get; set; }
        #endregion

        #region "获取或设置 安全标识"
        private string _SecurityStamp = "";
        /// <summary>
        /// 获取或设置 安全标识
        /// <para>每当用户凭据发生变化 (密码更改、登录、删除等) 时必须更改的随机值。</para>
        /// </summary>
        [Column("SecurityStamp")]
        [StringSize(StringSizeType.General)]
        [DisplayName("安全标识"), AuditIgnore]
        public string SecurityStamp { get { return _SecurityStamp; } set { _SecurityStamp = value.ReplaceNull(); } }
        #endregion

        #region "获取或设置 是否锁定当前信息"
        /// <summary>
        /// 获取或设置 是否锁定当前信息
        /// <para>ILockable 可装载接口，用于IEnumerable、IQueryable筛选</para>
        /// </summary>
        [Column("IsLocked")]
        [DisplayName("是否锁定")]
        public bool IsLocked { get; set; }
        #endregion

        #region "获取或设置 是否系统用户"
        /// <summary>
        /// 获取或设置 是否系统用户
        /// </summary>
        [Column("IsSystem")]
        [DisplayName("是否系统用户")]
        public bool IsSystem { get; set; }
        #endregion

        #region "获取或设置 创建时间 ICreatedTime、ICreationAudited  可装载接口，在数据创建时可自动设置当前时间"
        /// <summary>
        /// 获取或设置 创建时间
        /// </summary>
        [Column("CreatedTime")]
        [DisplayName("创建时间")]
        public DateTime CreatedTime { get; set; }
        #endregion

        #region "获取或设置 数据逻辑删除时间 ISoftDeletable 可装载接口，用于数据逻辑删除功能。注：Configuration文件中注意配置索引并且在最后增加 .IsUnique().HasFilter(null);"
        /// <summary>
        /// 获取或设置 数据逻辑删除时间
        /// （为 null 时表示为正常数据，有值表示已逻辑删除，同时删除时间每次不同也能保证索引唯一性）
        /// </summary>
        [Column("DeletedTime")]
        [DisplayName("删除时间")]
        public DateTime? DeletedTime { get; set; }
        #endregion

        #endregion

        #region "继承方法"
        #region "输出字符串-用户名"
        /// <summary>
        /// 输出字符串-用户名
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return UserName;
        }
        #endregion

        #endregion

    }
    #endregion

}
